<template>
  <div>
    <a-cascader 
      v-model:value="state.value" 
      :options="state.options" 
      :load-data="loadData"
      :field-names="{ label, value: id, children }" 
      :placeholder="placeholder" 
      change-on-select
      @dropdownVisibleChange="dropdownVisibleChange"
    />
  </div>
</template>
<script setup>
import { nextTick, onMounted, reactive, watch, computed } from "vue"
// utils
import { dataTypes } from "@/utils/index"
// api
import { areaList } from "@/api/public"
/**
 * props
 */
const props = defineProps({
  value: {
    type: Array,
    default: () => [],
  },
  placeholder: {
    type: String,
    default: "请选择",
  },
  label: {
    type: String,
    default: "name",
  },
  id: {
    type: String,
    default: "code",
  },
  width: {
    type: String,
    default: "100%",
  },
  defaultValue: {
    type: Array,
    default: () => [], // 具有上级层级的array对象
  },
  children: {
    type: String,
    default: "children",
  },
  isWorld: Boolean,
  // 最后一层
  deep: {
    type: Number,
    default: 3,
  },
  paramsChildKey: {
    type: String,
    default: "id",
  },
  paramsChildValueKey: {
    type: String,
    default: "id",
  },
  // 第一级请求，默认值
  paramsDefaultValue: {
    type: [Number, String],
    default: 0,
  },
  formatList: Function,
  selectLastLevel: Boolean,
  activeElemTop: Boolean, // 展开浮窗时，选中的元素是否置顶
})
/**
 * emit
 */
const emit = defineEmits(["change", "clear", "update:val"])
/**
 * state
 */
const state = reactive({
  pcode: ["320", "681", "732"],
  value: [],
  options: [],
  isLevelFirst: false,
  current: null
})
/**
 * 选择
 */
const handlerClear = () => {
  emit("update:val", [])
  emit("clear")
}
const handlerChange = (val) => {
  if (props.selectLastLevel) {
    if (val.length === props.deep) {
      emit("update:val", val)
    } else {
      emit("update:val", [])
    }
    return
  }
  emit("update:value", val)
  emit("change", val)
}
/**
 * 请求数据
 */
const getList = (value) => {
  return new Promise((resolve, reject) => {
    const level = state.current?.level || 0
    const type = {
      0: "province",
      1: "city",
      2: "area"
    }
    const req = {
      code: value || 0,
      type: type[level]
    }
    console.log('req', req)
    areaList(req)
      .then((res) => {
        const data = res.content
        // 标记isLeaf，false -> 异步下一层，true -> 结束
        data.forEach((item) => {
          item.isLeaf = (level === 2)
        })
        resolve(data)
      })
      .catch(() => {
        reject()
      })
  })
}
/**
 * 异步请求
 */
const loadData = (selectedOptions) => {
  // loading
  const targetOption = selectedOptions[selectedOptions.length - 1]
  targetOption.loading = true
  state.current = targetOption
  getList(targetOption[props.id])
    .then((res) => {
      targetOption.children = res
      state.options = [...state.options]
    })
    .finally(() => {
      targetOption.loading = false
    })
}
/**
 * 初始化
 */
const initLevelFirst = () => {
  return new Promise((resolve, reject) => {
    getList(props.paramsDefaultValue)
      .then((res) => {
        res.forEach(item => item.isLeaf = false)
        // 初次更新
        state.options = res
        resolve()
      })
      .catch(() => {
        reject()
      })
  })
}
onMounted(() => { })
/**
 * 默认值
 */
const initValue = () => {
  // 初始值结构体
  state.options = props.defaultValue
  // 获取初始值
  const ids = deepKey(props.defaultValue)
  state.value = ids
  state.isLevelFirst = false
}
/**
 * 递归获取字段
 */
const deepKey = (data) => {
  const isArray = dataTypes().isArray(data)
  if (!isArray) {
    return false
  }
  // 字段集合
  const ids = []
  // 递归
  const getKey = (d) => {
    d.forEach((item) => {
      ids.push(item[props.id])
      // 判断子级
      item.children && item.children.length && getKey(item.children)
    })
  }
  getKey(data)
  // 返回
  return ids
}

const getPopupContainer = (triggerNode) => triggerNode.parentNode

const dropdownVisibleChange = async (value) => {
  try {
    // 初始化第一级
    value && !state.isLevelFirst && (await initLevelFirst())
    state.isLevelFirst = true
    // 选中元素置顶
    value && props.activeElemTop && activeElemTop()
  } catch (error) { }
}

/**
 * 定位选中的元素置顶
 */
const activeElemTop = () => {
  let timer = null
  nextTick(() => {
    timer = setTimeout(() => {
      let list = document.querySelectorAll(".ant-cascader-menu")
      list = [...list]
      list.forEach((item) => {
        const parentDiv = item
        const childDiv = parentDiv.querySelector(".ant-cascader-menu-item-active")
        // 滚动指定的子元素到父元素的顶部
        childDiv.scrollIntoView({ behavior: "smooth", block: "start" })
        // 或者使用scrollTop
        parentDiv.scrollTop = childDiv.offsetTop - parentDiv.offsetTop - 4
      })
      // 清除定时器
      clearTimeout(timer)
      timer = null
    }, 0)
  })
}



watch(
  () => props.defaultValue,
  (val) => {
    if (!val || (val && !val.length)) {
      return false
    }
    initValue()
  },
  { immediate: true }
)
</script>
